#include <iostream>

// 单例模式：一个类只能创建一个对象
// 第一步：限制构造函数被调用——构造函数私有化（想定义对象或者想创建对象得通过构造函数，那就从构造函数上入手）
class Singleton
{
public:
    // 我们想要一个类只有一个对象，那就得限制在外部构建对象的过程，所以我们把构造函数私有了，这样在外部就不允许构造对象了，但是单例模式不是没有对象，得创建一个对象，那就从类内给对象，而类内给得通过函数，但是函数调用得需要一个对象，所以就变成了先有鸡还是先有蛋的问题
    // 第二步：提供一个静态函数接口，返回对象指针（静态函数可以很好的解决这个问题，静态函数调用不需要依赖对象）
    static Singleton* GetInstance()
    {
        // 最后一个问题：如何保证只有一个对象？
        // 构建一个对象，但这个对象只能出现一次，也就是这个对象只初始化一次
        // 第三步：在该静态函数接口定义静态局部变量，返回指针（静态局部变量只初始化一次，只有一个对象，因为它只初始化一次，所以返回它的指针只用一次）
        static Singleton s; // 只初始化一次
        return &s;
    }
    
    void show()
    {
        std::cout<<"hello world\n";
    }
private:
    // 构造函数私有化
    Singleton(){}   // 成功限制了在类的外部定义对象
};

int main()
{
    // 这三个指针的地址都相等，说明指向的是同一个对象，这就是单例
    Singleton *s1 = Singleton::GetInstance();
    Singleton *s2 = Singleton::GetInstance();
    Singleton *s3 = Singleton::GetInstance();
    printf("%p %p %p\n", s1, s2, s3);
    s1->show();
    s2->show();
    s3->show();

    return 0;
}